using System;
using System.Configuration;
using ClickOnceMaster.Helpers;

namespace ClickOnceMaster.WizardConfiguration
{
    /// <summary>
    /// Represents a configuration section group for the data generation settings.
    /// </summary>
    internal sealed class WizardSettings : ConfigurationSection
    {
        #region Consts

        /// <summary>
        /// The data generation configuration section group name.
        /// </summary>
        private const string SettingsSectionName = "wizardSettings";

        #endregion

        #region Static fields

        /// <summary>
        /// The synchronizer object that provides thread-safe access to the <see cref="Configuration"/> property.
        /// </summary>
        private static readonly object _configurationSynchronizer = new object();

        /// <summary>
        /// The synchronizer object that provides thread-safe access to the <see cref="Current"/> property.
        /// </summary>
        private static readonly object _settingsSynchronizer = new object();

        /// <summary>
        /// The configuration instance which the current settings section belongs to.
        /// </summary>
        private static Configuration _configuration;

        /// <summary>
        /// The current data generation settings.
        /// </summary>
        private static WizardSettings _current;

        #endregion

        #region Static properties

        /// <summary>
        /// Gets the current data generation settings.
        /// </summary>
        public static WizardSettings Current
        {
            get
            {
                lock (_settingsSynchronizer)
                {
                    if (_current == null)
                    {
                        _current = (WizardSettings)Configuration.GetSection(SettingsSectionName) ?? new WizardSettings();
                    }

                    return _current;
                }
            }
        }

        /// <summary>
        /// Gets the configuration instance which the current configuration section belongs to.
        /// </summary>
        private static Configuration Configuration
        {
            get
            {
                lock (_configurationSynchronizer)
                {
                    if (_configuration == null)
                    {
                        _configuration =
                            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
                    }

                    return _configuration;
                }
            }
        }

        #endregion

        #region Instance properties

        /// <summary>
        /// Gets the <see cref="ManifestSettings"/> instance.
        /// </summary>
        [ConfigurationProperty("manifest")]
        public ManifestSettings Manifest
        {
            get { return (ManifestSettings)this["manifest"]; }
        }

        #endregion

        #region Instance methods

        /// <summary>
        /// Saves the data generation settings to the appropriate configuration section.
        /// </summary>
        public void Save()
        {
            try
            {
                if (Configuration.Sections[SettingsSectionName] == null)
                {
                    Configuration.Sections.Add(SettingsSectionName, this);
                }

                Configuration.Save(ConfigurationSaveMode.Full);
            }
            catch (Exception e)
            {
                ExceptionHelper.HandleException(e);
            }
        }

        #endregion
    }
}